package lambda.lj1;


import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @file:
 * @version:
 * @Description: java8 将函数式接口封装到流中如何高效的帮助我们处理集合。
 * @author: 李津
 * @date: 2021-05-07 13:45
 * 本代码要注意的事项、备注事项等
 */

/**
 * 2、常用的流
 */
public class steamDemo {

    /**
     * 2.1 collect(Collectors.toList())
     * 将流转换为 list。还有 toSet()，toMap() 等。及早求值。
     */
    @Test
    public void collectStream() {
        Set<Student> students = Stream.of(
                new Student("路飞",21,180),
                new Student("礼金",21,180),
                new Student("红发",21,180)).
                collect(Collectors.toSet());
        System.out.println(students);
    }

    /**
     * 2.2 filter
     * 起过滤筛选的作用。内部就是 Predicate 接口。惰性求值。
     */
    @Test
    public void filterStream() {
        Set<Student> students2 = new LinkedHashSet<>(3);
        students2.add(new Student("路飞",21,180));
        students2.add(new Student("礼金",18,190));
        students2.add(new Student("红发",40,170));

        System.out.println(
                students2.stream().filter(st -> st.getHeight()>175)
                        .filter(student -> student.getAge()<20)
                        .collect(Collectors.toSet()));
    }

    /**
     * 2.3 map
     * 转换功能，内部就是 Function 接口。惰性求值
     */
    @Test
    public void mapStream() {
        Set<Student> students3 = new LinkedHashSet<>(3);
        students3.add(new Student("路飞",21,180));
        students3.add(new Student("礼金",21,190));
        students3.add(new Student("红发",21,170));

        System.out.println(
                students3.stream().map(student -> student.getName())
                        .collect(Collectors.toSet())
        );
        System.out.println(
                students3.stream().map(Student::getName)
                        .collect(Collectors.toSet())
        );
    }

    /**
     * 2.4 flatMap
     * 流可以容纳复杂的数据结构，比如 Stream < List < string > 。在这种情况下，flatMap ()可以帮助我们展开数据结构，以简化进一步的操作:
     * 将多个 Stream 合并为一个 Stream。惰性求值
     */
    @Test
    public void flatMapStream() {
        List<List<String>> namesNested = Arrays.asList(
                Arrays.asList("Jeff", "Bezos"),
                Arrays.asList("Bill", "Gates"),
                Arrays.asList("Mark", "Zuckerberg"));

        List<String> namesFlatStream = namesNested.stream()
                .flatMap(Collection::stream)
                .collect(Collectors.toList());

        System.out.println(namesFlatStream);
    }

    /**
     * 2.5 max 和 min
     * 在集合中求最大或最小值，使用流就很方便。及早求值。
     * max、min 接收一个 Comparator（例子中使用 java8 自带的静态函数，只需要传进需要比较值即可。）并且返回一个 Optional 对象，该对象是 java8 新增的类，专门为了防止 null 引发的空指针异常。
     */
    @Test
    public void mStream() {
        Set<Student> students4 = new LinkedHashSet<>(3);
        students4.add(new Student("路飞",21,180));
        students4.add(new Student("礼金",18,190));
        students4.add(new Student("红发",40,170));

        Optional<Student> max = students4.stream().max(Comparator.comparing(Student::getAge));
        Optional<Student> min = students4.stream().min(Comparator.comparing(Student::getAge));

        if (max.isPresent()){
            System.out.println(max.get());
        }

        min.ifPresent(System.out::println);
    }

    /**
     * 2.6 count
     * 统计功能，一般都是结合 filter 使用，因为先筛选出我们需要的再统计即可。及早求值
     */
    @Test
    public void countStream() {
        Set<Student> students5 = new LinkedHashSet<>(3);
        students5.add(new Student("路飞",21,180));
        students5.add(new Student("礼金",18,190));
        students5.add(new Student("红发",40,170));

        Long count = students5.stream().filter(st -> st.getAge() > 20).count();
        System.out.println(count);
    }

    /**
     * 2.7 reduce
     * reduce 操作可以实现从一组值中生成一个值。
     * 在上述例子中用到的 count 、 min 和 max 方法，因为常用而被纳入标准库中。
     * 事实上，这些方法都是 reduce 操作。及早求值。
     */
    @Test
    public void reduceStream(){
//        Integer reduce = Stream.of(1,2,3,4).reduce(0,(x,y)-> x+y);
        Integer reduce = Stream.of(1,2,3,4).reduce(0, Integer::sum);
        System.out.println(reduce);
    }


}
